package wechatService

import (
	"github.com/chanxuehong/wechat.v2/mp/core"
	"github.com/chanxuehong/wechat.v2/mp/qrcode"
	"github.com/chanxuehong/wechat.v2/mp/user"
	"image"
	"image/png"
	"net/http"
	"fmt"
	"strconv"
	"log"
	"unsafe"
	"sync/atomic"
	"io/ioutil"
	"github.com/astaxie/beego"
	"github.com/fogleman/gg"
	"github.com/astaxie/beego/logs"
	"errors"
)

var _ core.AccessTokenServer = (*RPCAccessTokenServer)(nil)

var rPCAccessTokenServer *RPCAccessTokenServer = NewRPCAccessTokenServer(nil)
var wechatClient *core.Client = core.NewClient(rPCAccessTokenServer, nil)


// RPCAccessTokenServer 实现了 AccessTokenServer 接口.
//  NOTE:
//  1. 用于单进程环境.
//  2. 因为 DefaultAccessTokenServer 同时也是一个简单的中控服务器, 而不是仅仅实现 AccessTokenServer 接口,
//     所以整个系统只能存在一个 DefaultAccessTokenServer 实例!
type RPCAccessTokenServer struct {
	appId      string
	appSecret  string
	httpClient *http.Client

	tokenCache unsafe.Pointer // *accessToken
}

func NewRPCAccessTokenServer(httpClient *http.Client) (srv *RPCAccessTokenServer) {
	if httpClient == nil {
		httpClient = http.DefaultClient
	}

	srv = &RPCAccessTokenServer{
		appId:                    "",
		appSecret:                "",
		httpClient:               httpClient,
	}

	return
}

type accessToken struct {
	Token     string `json:"access_token"`
	ExpiresIn int64  `json:"expires_in"`
}



func (srv *RPCAccessTokenServer) Token() (token string, err error) {
	if p := (*accessToken)(atomic.LoadPointer(&srv.tokenCache)); p != nil {
		return p.Token, nil
	}
	return srv.RefreshToken("")
}

type refreshTokenResult struct {
	token string
	err   error
}

func (srv *RPCAccessTokenServer) IID01332E16DF5011E5A9D5A4DB30FED8E1() {}


func (srv *RPCAccessTokenServer) RefreshToken(currentToken string) (token string, err error) {
	res, err := http.Get(beego.AppConfig.String("RPC_ACCESS_TOKEN_URL"))
	if err != nil || res.StatusCode != 200 {
		fmt.Println("get access token error: " + strconv.Itoa(res.StatusCode))
	}
	if res == nil {
		fmt.Println("get access token err: res is nil")
		return "", errors.New("get access token err: res is nil")
	}
	if res.StatusCode != 200 {
		fmt.Println("get access token err:  statusCode is " + strconv.Itoa(res.StatusCode))
		return "", errors.New("get iaccess token err:  statusCode is " + strconv.Itoa(res.StatusCode))
	}

	defer res.Body.Close()

	token_byte, err := ioutil.ReadAll(res.Body) //<--- here!
	if err != nil {
		fmt.Println(err)
	}
	token = string(token_byte)

	return token, nil
}

func GetUserQRCode(userId int32, temp bool) (img image.Image, err error) {
	var qrTicket string
	if temp {
		tempQrCode, err := qrcode.CreateTempQrcode(wechatClient, userId,2592000)
		if err != nil {
			return nil, err
		}
		qrTicket = tempQrCode.Ticket
	} else {
		log.Println("永久二维码: " + strconv.Itoa(int(userId)))
		permQrCode, _ := qrcode.CreateStrScenePermQrcode(wechatClient, strconv.Itoa(int(userId)))
		qrTicket = permQrCode.Ticket
	}
	qrUrl := "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + qrTicket

	res, err := http.Get(qrUrl)
	logs.Debug(res)

	if err != nil{

		fmt.Println("get image url error: " + err.Error())
		return nil,err
	}
	if res == nil {
		fmt.Println("get image url err: res is nil")
		return nil, errors.New("get image url err: res is nil")
	}
	if res.StatusCode != 200 {
		fmt.Println("get image url err:  statusCode is " + strconv.Itoa(res.StatusCode))
		return nil, errors.New("get image url err:  statusCode is " + strconv.Itoa(res.StatusCode))
	}

	defer res.Body.Close()

	img, _, err = image.Decode(res.Body)

	if err != nil {
		fmt.Println(err)
	}

	return
}

func GetAvatar(openId string) (img image.Image, err error) {
	userInfo, err := user.Get(wechatClient, openId, user.LanguageZhCN)

	if err != nil {
		fmt.Println(err)
		return
	}

	//fmt.Println(userInfo)

	if userInfo.HeadImageURL != "" {

		res, err := http.Get(userInfo.HeadImageURL)
		if err != nil {
			fmt.Println("get avatar url error: " + err.Error())
			return nil,err

		}
		if res == nil {
			fmt.Println("get avatar url err: res is nil")
			return nil, errors.New("get image url err: res is nil")
		}
		if res.StatusCode != 200 {
			fmt.Println("get avatar url err:  statusCode is " + strconv.Itoa(res.StatusCode))
			return nil, errors.New("get avatar url err:  statusCode is " + strconv.Itoa(res.StatusCode))
		}

		defer res.Body.Close()

		img, _, err = image.Decode(res.Body)
		if err != nil {
			fmt.Println(err)
			img, err = png.Decode(res.Body)
			if err != nil {
				fmt.Println(err)
			}
		}

	} else {
		// 如果用户没有头像，则使用默认头像
		img, err = gg.LoadImage("static/img/avatar.jpg")
		if err != nil {
			log.Fatal(err)
		}

	}

	return
}



